import numpy as np

from scipy import linalg
from sympy import Matrix
import torch
# ra=np.random.randint(0,5,8) #随机数
# # print(ra)
# # print(np.unique(ra))#去重，并升序排序 [0 1 2 3 4]
# # print(np.zeros((2,5)))#零元矩阵
a2dim = np.array([[1,2,3], [4,5,6]])

# a_b=np.concatenate((a2dim,a2dim),axis=0)#同维连接，按最高维
# # print(a_b)
# ##np.cumsum累加：axis=0，按照行累加。axis=1，按照列累加。axis不给定具体值，就把numpy数组当成一个一维数组并往后累加。
# asum=np.cumsum(a2dim, axis=None, dtype=None, out=None)
# # print(asum)#[ 1  3  6 10 15 21]#第1个数不变
# # print(np.cumsum(a,axis=1))#按列累加（第1列不变）
# # print('*{}' * 30)#打印相同内容
# # print('*{},{}'.format(asum,asum) )#格式化输出
# # f=0.235465
# # far = np.around(f, decimals=4)  # 小数点四舍五入，保留4位
# # print(far)
# # a=[1,2,3]
# # b=[1,2,4]
# # print(a==b)#默认判等，全等才为True
# # print(1==a)
# #切片a[start:stop:step],左闭右开，负数表示倒数
# a_9=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# # print(a_9[:4:-2])#stop的4按正序，[9, 7, 5]
#
# a3 = torch.arange(10).reshape(5,2)
# # print(a3)
#
# a4=torch.split(a3,[1,2,2])
# # print(a4)

# a3_tor = torch.from_numpy(a3) # numpy 2 tensor
# t.numpy()           # tensor 2 numpy
# a5=torch.cat((a3,a3),1)#* (tuple of Tensors tensors, int dim, *, Tensor out)
# # print(a5)
# a6=torch.arange(0, 5) % 3
# print(a6)


# # a7 = np.array([[1, 1,1], [-1,3,3],[0,2,2]]) # 初始化一个非奇异矩阵(数组)
# a7=np.array([[1, 1,0], [0,2,2],[0,0,0]])
# #不可逆时报错：numpy.linalg.LinAlgError: Singular matrix
# # a7_inv=np.linalg.inv(a7)#逆矩阵-取反
# # a7_inv_int=a7_inv.astype(np.int16)#矩阵的数据类型转换
# # a7_inv_round=np.round(a7_inv,1)#圆整-保留小数位数
# # print(a7_inv)
# # print(a7_inv_round)
# a7_rank=np.linalg.matrix_rank(a7)#矩阵的秩
# print("矩阵的秩:",a7_rank)


#start-计算矩阵的秩、行列式、迹，特征值和特征向量、
# import numpy as np
from fractions import Fraction
# np.set_printoptions(precision=2) #设置np.array的小数位数为2位
# np.set_printoptions(formatter={'all':lambda x: str(Fraction(x).limit_denominator())})#设置np.array用分数表示
# a = np.array([[3,1,0,0],
#               [0,3,0,0],
#               [0,0,1,1],
#               [0,0,-2,4]])
# a = np.array([[0.2,0.1,0.2], [0.5,0.5,0.4], [0.1,0.3,0.2]])
# a=np.array([[1,0,0], [0,1,0], [-1,-2,2]])
a = np.array([[1,3],
             [2,2]])

print("矩阵的秩:",np.linalg.matrix_rank(a))#返回矩阵的秩
np.linalg.det(a) #返回矩阵的行列式
a.diagonal() #返回矩阵的对角线元素，也可以通过offset参数在主角线的上下偏移，获取偏移后的对角线元素。a.diagonal(offset=1)返回array([1.10])
a.trace()#返回迹,主对角线上各个元素的总和被称为矩阵A的迹（或迹数），一般记作tr(A)。
eigenvalues ,eigenvectors= np.linalg.eig(a) #eigenvalues 为特征值。eigenvectors为特征向量#要求是方阵
print("eigenvalues:",eigenvalues)
for λ in eigenvalues:
    eigen_matrix = a - np.eye(a.shape[0]) * λ  # 特征矩阵A-λE(对指定特征值)
    #控制输出：list保留小数位数
    print("特征值", '%.2f'%λ, "有", a.shape[0] - np.linalg.matrix_rank(eigen_matrix), "个线性无关的特征向量")  # 特征矩阵的秩
# λ=int(eigenvalues[1])#取特征值
# eigen_matrix=a-np.eye(a.shape[0])*λ#特征矩阵A-λE(对指定特征值)
print("eigenvectors:",eigenvectors)
# print("特征值",λ,"对应特征矩阵的秩:",np.linalg.matrix_rank(eigen_matrix))#特征矩阵的秩
# print("特征值",λ,"有",a.shape[0]-np.linalg.matrix_rank(eigen_matrix),"个线性无关的特征向量")#特征矩阵的秩
#end-计算矩阵的秩、行列式、迹，特征值和特征向量


# #  求解线性方程组
#
# from scipy import linalg
# import numpy as np
# #求解Ax=b
# # x1 + x2 + 7*x3 = 2
# # 2*x1 + 3*x2 + 5*x3 = 3
# # 4*x1 + 2*x2 + 6*x3 = 4
#
# A = np.array([[1, 1, 7], [2, 3, 5], [4, 2, 6]])  # A代表系数矩阵
# b = np.array([2, 3, 4])  # b代表常数列
# x = linalg.solve(A, b)#或者用np库：c=np.linalg.solve(A,b)#A要求是方阵
# # print(x)

# #start-矩阵的秩，逆矩阵和行最简形
# #功能：由向量生成矩阵
# a1=np.array([1, 3, 4,1])
# # a1_trans=np.transpose(a1)#矩阵转置
# a1_trans=a1.T#矩阵转置:向量转置还是本身
# a2=np.array([1,0,1,1])#默认行向量
# a3=np.array([-1,1,2,0])
# a4=np.array([0,1,1,0])
# a5=np.array([1,2,1,0])
# # A=np.array([a1,a2,a3,a4,a5])
# # A=np.array([[1,2,1,0],[0,1,0,0],[0,0,0,1],[0,0,1,-1]])
# A=np.array([[1,2,3],[-1,0,3],[2,1,5]])
# A_rank=np.linalg.matrix_rank(A)
# # print(A.T)#矩阵的转置
# print("矩阵A的秩:",A_rank)#矩阵的秩
# B=np.array([[1,1,1],[0,1,1],[0,0,1]])
# B_inv=np.linalg.pinv(B)#B的逆矩阵
# Q=B_inv.dot(A).dot(B)
# print(Q)#B-1*A*B
# # A_reve_global=np.linalg.pinv(A)#广义逆（也叫“伪逆”）-非方阵求逆
# # print("矩阵的广义逆（也叫“伪逆”）：",A_reve_global)
# # b = np.random.rand(5,1)
# # x=A_reve_global.dot(b)#解方程Ax=b-齐非次方程求解-非方阵求解（近似解）
# # print(x)
# # print(np.sum(abs(A.dot(x)-b)))#验证近似解-值为误差
#
# #将矩阵做初等行变换求行最简
# # rref = Matrix(np.array(A.T)).rref()[0].tolist()#转置
# rref = Matrix(np.array(A)).rref()[0].tolist()
# print("矩阵行最简式：",rref)
# #end-矩阵的秩，逆矩阵和行最简形

# #施密特正交化（分数显示）-start
# #https://blog.csdn.net/ouening/article/details/83279894
# from sympy import Matrix,GramSchmidt
# L = [Matrix([1,2,3]), Matrix([2,1,3]), Matrix([3,2,1])]#待正交化向量组
# o1=GramSchmidt(L)#正交基
# print(o1)
# # o2=GramSchmidt(L,True) # 单位化正交基/标准
# # print(o2)
# #施密特正交化（分数显示）-end

# a_diag=linalg.block_diag(a, a)#由已有矩阵构建对角块矩阵
# print("a_diag:",a_diag)